
OLD_IFS="$IFS"      


 
 
function The_image_in_the_node {        # 函数开始 The_image_in_the_node
 

read -p "Enter node name: " node_name

node_name_if=$(echo $node_name |sed 's/ //g')    # 去除变量中的空格，不然如果你输入的变量中有空格，判断就会失去效果

if [[ "$node_name_if" =~ ^[0-9]+$ ]]; then   
    node_name=$(kubectl  get node | sed '1d' | awk '{print $1}' | sed -n "${node_name}p")
else
    :
fi

kubectl get pods -A -o wide --field-selector=spec.nodeName=${node_name} | sed '1d' | awk '$1 != "kube-system"' | awk '{print$1}' > ./ns.txt
kubectl get pods -A -o wide --field-selector=spec.nodeName=${node_name} | sed '1d' | awk '$1 != "kube-system"' | awk '{print$2}' > ./pod.txt

Counting="0"
  > ./images.txt
for ns_for in $(cat ./ns.txt) ;do
Counting=$((++Counting))
kubectl  describe pod -n ${ns_for} $(sed -n "${Counting}p" ./pod.txt)  | egrep "Image:" | awk '{print$2}'  >> ./images.txt
 
done
cat ./images.txt | uniq

rm -fr ./images.txt  ./ns.txt  ./pod.txt 
}                       # 函数结束 The_image_in_the_node




function All_images_used_under_the_namespace {    # 函数开始 All_images_used_under_the_namespac

read -p "Enter namespace: " namespace
namespace_if=$(echo $namespace |sed 's/ //g')    # 去除变量中的空格，不然如果你输入的变量中有空格，判断就会失去效果

if [[ "$namespace_if" =~ ^[0-9]+$ ]]; then   
    namespace=$(kubectl  get ns | sed '1d' | awk '{print $1}' | sed -n "${namespace}p")
else
    :
fi


    if [ $(kubectl get deployments.apps -n ${namespace} 2>/dev/null | wc -l) -eq 0 ]; then
          echo -e "\033[38;5;214mno deployments.apps\033[0m"

      fi  
for i in $(kubectl  get deployments.apps -n ${namespace}  2>/dev/null | sed '1d' | awk '{print $1}');do     # deployments 
          kubectl  describe deployments.apps -n ${namespace} ${i} | egrep -w "Image:" | awk '{print $2}' | uniq
done




    if [ $(kubectl get statefulsets.apps -n ${namespace} 2>/dev/null | wc -l) -eq 0 ]; then
          echo -e "\033[38;5;214mno statefulsets.apps\033[0m"

      fi  
for i in $(kubectl  get statefulsets.apps -n ${namespace} 2>/dev/null | sed '1d' | awk '{print $1}');do     # statefulsets.apps 
           kubectl  describe statefulsets.apps  -n ${namespace} ${i} | egrep -w "Image:" | awk '{print $2}' | uniq 
done


    if [ $(kubectl get daemonsets.apps -n ${namespace} 2>/dev/null | wc -l) -eq 0 ]; then
          echo -e "\033[38;5;214mno daemonsets.apps\033[0m"
      fi  
for i in $(kubectl  get daemonsets.apps -n ${namespace}  2>/dev/null | sed '1d' | awk '{print $1}');do     # daemonsets.apps
       kubectl  describe daemonsets.apps -n ${namespace} ${i} | egrep -w "Image:" | awk '{print $2}' | uniq
done



}   # 函数结束  All_images_used_under_the_namespace




function Extract_Node_Taints {             # 函数开始：  Extract_Node_Taints

node_taints=$(kubectl describe node ${node_name} | sed -n '/Taints:/,/Unschedulable:/P' | sed '/Unschedulable:/Q'  | sed 's/Taints://g' | sed 's/ //g' )
for i in $node_taints;do
echo -e "\t\t$i"
done


}                                           # # 函数结束：  Extract_Node_Taints



function pod_node_labels {                  # 函数开始： pod_node_labels

  read -p "Enter node name: " node_name
    
     node_name=$(echo $node_name |sed 's/ //g') 
      if [[ "$node_name" =~ ^[0-9]+$ ]]; then   
          node_name=$(kubectl  get node | sed '1d' | awk '{print$1}' | sed -n "${node_name}p")
      else
        :
      fi

  kubectl get ns |  sed '1d' | awk '{print NR". "$1}'  > ns.txt

        sed_start="1"
        sed_end="3"



if [ $(echo "scale=1; $(wc -l ns.txt | awk '{print $1}')/3" | bc | awk -F '.' '{print $2}')  -eq 0 ]; then

  line=$(echo "scale=1; $(wc -l ns.txt | awk '{print $1}')/3" | bc) 
else
  line=$(echo "scale=0; $(wc -l ns.txt | awk '{print $1}')/3" + 1 | bc)

fi



for i in $(seq 1 ${line});do
     sed -n "${sed_start},${sed_end}p" ns.txt   | sed ':a;N;$!ba;s/\n/\t\t\t/g'
     echo ""
     for i in {1..3};do
      sed_end=$((++sed_end))
      sed_start=$((++sed_start))
     done
done

  read -p "Enter pod_namespces name: " pod_ns
      pod_ns_if=$(echo $pod_ns |sed 's/ //g')    

      if [[ "$pod_ns_if" =~ ^[0-9]+$ ]]; then   
          pod_ns=$(awk -F '.' '{print $2}' ns.txt  | sed 's/^[[:space:]]*//'| sed -n "${pod_ns}p")

      else
          :
      fi


  kubectl  get pod -n${pod_ns} | sed '1d'  | awk '{print NR". "$1}'
  read -p "Please enter the pod name or index (separate multiple entries with spaces): " pod_name


IFS=' '  
for pod_name in ${pod_name};do

     pod_name=$(echo $pod_name |sed 's/ //g') 
      if [[ "$pod_name" =~ ^[0-9]+$ ]]; then   
          pod_name=$(kubectl  get pod -n ${pod_ns}| sed '1d' | awk '{print$1}' | sed -n "${pod_name}p")
      else
        :
      fi

  kubectl get node ${node_name} --show-labels | awk '{print $6}' | sed '1d;s/,/\n/g' > ./node_labels.txt 
  kubectl get pod ${pod_name} -n ${pod_ns} -o yaml |egrep -v "f:nodeSelector:" |grep -A 8 -w nodeSelector | sed '1d' | sed '/preemptionPolicy/Q' | sed 's/: /=/g' | tr -d '"'  | sed 's/^[[:space:]]*//' > ./pod_lables.txt


  if grep -q '[^[:space:]]' ./pod_lables.txt  > /dev/null 2>&1; then
    :
  else
    echo -e "\n${pod_name}: "
    echo -e "\033[32mThis pod does not have nodeSelector\033[0m"
    rm -fr ./node_labels.txt ./pod_lables.txt ns.txt 
    rm -fr cpu.txt mem.txt name.txt ns.txt

    continue
  fi

  echo -e "\n${pod_name}(pod) and ${node_name}(node) Configuration Match Check"
  IFS=$'\n'
  echo -e "\tLabel Matching Comparison: "
  for pod_labels_for in $(cat ./pod_lables.txt); do
    if fgrep -w "${pod_labels_for}" ./node_labels.txt > /dev/null 2>&1; then
      echo -e "\t\t\033[0;32mPod with label ${pod_labels_for} exists on node ${node_name}\033[0m" 
     
    else
      echo -e "\t\t\033[0;31mThe tag ${pod_labels_for} is not on node ${node_name}\033[0m"
      
    fi
  done


### 将pod容忍与node污点匹配#######
kubectl describe pod  ${pod_name}  -n ${pod_ns} | sed -n '/Tolerations:/,/Events:/P' | sed '/Events:/Q'  | sed 's/Tolerations://g'  | awk '{print$1}' | fgrep -wv "node.kubernetes.io/not-ready:NoExecute" | fgrep -wv "node.kubernetes.io/unreachable:NoExecute"  > ./pod_Tolerations.txt
kubectl describe node ${node_name} | sed -n '/Taints:/,/Unschedulable:/P' | sed '/Unschedulable:/Q'  | sed 's/Taints://g' | sed 's/ //g' |egrep -v "PreferNoSchedule"  > node_taints.txt
echo -e "\ttolerations and taints: "



if [ $(cat ./node_taints.txt | grep -v '^$'| wc -l) -eq 0 ] ; then     # 判断node是否有污点
    echo -e "\033[32m\t\tNode ${node_name} has no taints,or the node has a PreferNoSchedule taint.\033[0m"
    continue
elif [ $(cat ./node_taints.txt | sed -n "1p") == "<none>" ] ; then
        echo -e "\033[32m\t\tNode ${node_name} has no taints,or the node has a PreferNoSchedule taint.\033[0m"
    continue
else
    :
fi









if [ $(cat ./pod_Tolerations.txt | grep -v '^$'| wc -l) -eq 0 ] && [ $(cat ./node_taints.txt | grep -v '^$' | fgrep -v "<none>"| wc -l) -gt 0 ] ; then   # 判断 node有污点而pod没有容忍
  

    echo -e "\t\t\033[31mThe Pod lacks tolerations, while the Node has taints.\033[0m"   
    continue   

else
    :
fi



  for i in $(cat ./node_taints.txt);do

    if fgrep -w "${i}" ./pod_Tolerations.txt > /dev/null 2>&1 ; then         # 判断 pod 容忍是否匹配node污点

        echo -e "\t\t\033[32mThe toleration \033[37m${i}\033[32m in the Pod matches the taint on the node\033[0m"

     else
       echo -e "\t\t\033[31mThe toleration in the Pod does not match the taint \033[37m${i}\033[31m on the node\033[0m"
       
    fi
  done
  ### 将pod容忍与node污点匹配结束#######


done
}                           #   函数stop： pod_node_labels





function resource_usage_node {               # 函数start： resource_usage_node

node_cpu_total=$(kubectl describe node $node_name | grep -A9 "Capacity" |sed '/Allocatable:/Q' | grep "cpu:" | awk '{print $2}')
node_mem_total_ki=$(kubectl describe node $node_name | grep -A9 "Capacity:" |sed '/Allocatable:/Q'| grep "memory:" | awk '{print $2}' | sed 's/Ki//')
node_mem_total=$(echo "scale=2; $node_mem_total_ki/1024/1024" | bc)
node_pod_ns=$(kubectl get pods -A --field-selector spec.nodeName=$node_name | sed '1d' | awk '{print $1}')  
node_pod_name=$(kubectl get pods -A --field-selector spec.nodeName=$node_name | sed '1d' | awk '{print $2}')  

echo "$node_pod_ns" >  ./ns.txt
echo "$node_pod_name" >  ./name.txt






# #### 求node-cpu使用情况########


IFS=$'\n' 
sed_num=0
 > ./cpu.txt
for ns in $node_pod_ns;do
    sed_num=$((sed_num + 1))

  for name in $(cat ./name.txt | sed -n "${sed_num}p");do
   
    kubectl get pod -n $ns $name -o yaml | egrep  -A 1 "requests"  | egrep "cpu:" | awk '{print $2}' >> ./cpu.txt
   
  done

done



cpu_total=0
for cpu_txt in $(cat ./cpu.txt);do

  if [[ "$cpu_txt" =~ m ]]; then   
     
     cpu_total=$(echo "scale=2; $(echo $cpu_txt | tr -d 'm')/1000" + $cpu_total | bc)
    
  else
    cpu_total=$(echo "scale=2; $(echo $cpu_txt | tr -d '"')" + $cpu_total | bc)
  fi 
 

done

#####################


IFS=$'\n' 
sed_num=0
 > ./mem.txt
for ns in $node_pod_ns;do
    sed_num=$((sed_num + 1))

  for name in $(cat ./name.txt | sed -n "${sed_num}p");do
   
    kubectl get pod -n $ns $name -o yaml | egrep  -A 2 "requests"  | egrep "memory:" | awk '{print $2}' >> ./mem.txt
   
  done

done



mem_total=0
for mem_txt in $(cat ./mem.txt);do

  if [[ "$mem_txt" =~ Mi ]]; then   
     
     mem_total=$(echo "scale=5; $(echo $mem_txt | tr -d 'Mi')/1024" + $mem_total | bc)   # Mi
  elif [[ "$mem_txt" =~ Gi ]]; then
    mem_total=$(echo "scale=5; $(echo $mem_txt | tr -d 'Gi')" + $mem_total | bc)    # Gi
    
  else
      :
  fi 


done



############ node 为pod 可分配资源总数#################


## node 可以为pod分配的资源总和 mem ##
if [[ $(kubectl get node ${node_name}  -o jsonpath='{.status.allocatable.cpu} {.status.allocatable.memory}' | awk '{print $2}') =~ Ki ]]; then 
	Fix_pod_resource_mem_total=$(kubectl get node ${node_name}  -o jsonpath='{.status.allocatable.cpu} {.status.allocatable.memory}' | awk '{print $2}' | tr -d 'Ki')


	Fix_pod_resource_mem_total=$(echo "scale=3; $Fix_pod_resource_mem_total/1048576" | bc)



else
	Fix_pod_resource_mem_total=$(kubectl get node ${node_name}  -o jsonpath='{.status.allocatable.cpu} {.status.allocatable.memory}' | awk '{print $2}' | tr -d 'Ki')
	Fix_pod_resource_mem_total=$(echo "scale=3; $Fix_pod_resource_mem_total/1073741824" | bc)
 
fi



#####求资源使用占比####
cpu_resource_usage_ratio=$(echo "scale=2; ${cpu_total}/${node_cpu_total} * 100" | bc) 
mem_resource_usage_ratio=$(echo "scale=2; ${mem_total}/${Fix_pod_resource_mem_total} * 100" | bc) 

###########

 node_CPU_usage=$(kubectl top node | sed '1d' | egrep -w $node_name | awk '{print $3}')
 node_MEM_usage=$(kubectl top node | sed '1d' | egrep -w $node_name | awk '{print $5}')

###########总结##############
echo -e "\n\n\033[34m$node_name\033[0m 资源使用情况如下："

echo -e "\tCurrent node CPU usage: ${node_CPU_usage}"
echo -e "\tCurrent node MEM usage: ${node_MEM_usage}"
echo  -e "\tThe total CPU resources available for allocation to Pods: ${node_cpu_total} vCPU"
echo -e "\tThe total mem resources available for allocation to Pods: ${Fix_pod_resource_mem_total}G"
echo -e  "\tThe total memory requested by the Pods：${mem_total}G   (mem usage:${mem_resource_usage_ratio}%)" 
echo -e "\tThe total CPU requested by the Pods：${cpu_total} vCPU   (CPU usage:${cpu_resource_usage_ratio}%)"

echo -e "\tThe taint contained in the node:"
Extract_Node_Taints

echo -e "\tNumber of pods in each namespace(excluding kube-system) : "
for ns_for in $(sort ns.txt | uniq | egrep -vi "kube-system");do
        echo -e "\t\t${ns_for} : $(kubectl get pods -A -o wide --field-selector=spec.nodeName=$node_name | awk '{print $1}' | sed '1d' | egrep -w "$ns_for" | wc -l) "
done


echo -e "\n\tNode labels:"


for node_labels_for in $(kubectl get node ${node_name} --show-labels | awk '{print $6}' | sed '1d;s/,/\n/g' | sort);do
echo -e "\t\t$node_labels_for"
done

echo -e "\n\n\033[38;5;214m--------------------\033[0m"



}         # 函数stop： resource_usage_node




###############函数的调用######
read -p $'1、Node Resource Check\n2、Pod vs Node label comparison\n3、Using Image Detection\nSelect the function you want to execute: ' function

if [ $function == 1 ]; then
    tput clear
    kubectl get node | sed '1d' | awk '{print $1}' | nl

    read -p "Please enter the serial number(s) or node name(s) (multiple values separated by spaces):  " node_index
    IFS=' '
    for node_index_for in ${node_index}; do

    node_index_if=$(echo $node_index_for |sed 's/ //g')    

    if [[ "$node_index_if" =~ ^[0-9]+$ ]]; then   
      
      node_name=$(kubectl get node | sed '1d' | awk '{print $1}' | sed -n "${node_index_for}p")
        
    else  
            node_name=$node_index_for
      
    fi
             

            resource_usage_node

    done
rm -fr ./node_labels.txt ./pod_lables.txt ns.txt ./cpu.txt mem.txt ./name.txt ns.txt ./node_taints.txt  ./pod_Tolerations.txt   


elif [ $function == 2 ]; then
        tput clear
    kubectl get node | sed '1d' | awk '{print $1}' | nl

    pod_node_labels

rm -fr ./node_labels.txt ./pod_lables.txt ns.txt ./cpu.txt mem.txt ./name.txt ns.txt ./node_taints.txt  ./pod_Tolerations.txt     



elif [ $function == 3 ]; then
  tput clear
  echo -e "\n1、Namespace Dimension\n2、Node Dimension"
  read -p "Select Your Dimension: " dimension
  if [ $dimension == 1 ]; then
      tput clear
    kubectl get ns | sed '1d' | awk '{print NR". "$1}' | paste - - -
   All_images_used_under_the_namespace 
   rm -fr deployments.txt statefulsets.apps.txt 
  elif [ $dimension == 2 ];then
          tput clear
           kubectl  get node | sed '1d' |awk '{print $1}' | awk '{print NR". "$1}'
          The_image_in_the_node
   
  fi




  
fi

